"""多线程TCP IO 密集型并发模型 FTP服务端"""
# ! usr/bin/env python3
# coding="UTF-8"
# @author:WeiJunJie
# @email:0234934819@163.com
# @date:2024/1/22
import os
import sys
from socket import *
from threading import Thread
import time


# 线程类
class FTPServer(Thread):
    def __init__(self, conn):
        super().__init__()
        self.conn = conn

    def __do_list(self):
        # 获取文件列表
        file_list = os.listdir(".")
        if not file_list:
            self.conn.send("文件库为空".encode())
            return
        else:
            self.conn.send(b"OK")
            time.sleep(0.1)
            # 拼接文件名
            files = ""
            for file in file_list:
                if file[0] != "." and os.path.isfile(ServerMain.FTP_ADDR + file):
                    files += file + "\n"
            self.conn.send(files.encode())

    def __download(self, filename):
        try:
            f = open(ServerMain.FTP_ADDR + filename, "rb")
        except Exception:
            self.conn.send("文件不存在".encode())
            return
        else:
            self.conn.send(b"OK")
            time.sleep(1)
            while True:
                data = f.read(1024)
                if not data:
                    time.sleep(0.1)
                    self.conn.send(b"##")
                    break
                self.conn.send(data)

    def __get_file(self, filename):
        if os.path.exists(ServerMain.FTP_ADDR+filename):
            self.conn.send(b"file exist")
            return
        self.conn.send(b"OK")
        code = self.conn.recv(108).decode()
        if code == "Error":
            print("客户端没有此文件")
        else:
            time.sleep(1)
            f = open(filename, "wb")
            while True:
                data = self.conn.recv(1024)
                if data == b"##":
                    return
                f.write(data)

    def run(self):
        while True:
            data = self.conn.recv(1024).decode()
            if not data or data == "E":
                return
            elif data == 'L':
                self.__do_list()
            elif data[0] == "D":
                filename = data.split(" ")[-1]
                self.__download(filename)
            elif data[0] == "U":
                filename = data.split(" ")[-1]
                self.__get_file(filename)


# 服务器类
class ServerMain:
    HOST = '127.0.0.1'
    PORT = 5555
    ADDR = (HOST, PORT)
    FTP_ADDR = r"E:\Study_PYTHON\网络编程\项目练习\多线程TCP通信实现\\"
    conn = None

    def main(self):
        server = socket(AF_INET, SOCK_STREAM)
        server.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
        server.bind(self.ADDR)
        server.listen(5)
        """等待客户端连接"""
        while True:
            try:
                print("waiting for connection...")
                self.conn, addr = server.accept()
                print("connected by", addr)
            except KeyboardInterrupt:
                sys.exit("服务器退出")
            except Exception as e:
                print(e)
                continue
            t = FTPServer(self.conn)
            t.daemon = True
            t.start()


if __name__ == '__main__':
    server = ServerMain()
    server.main()
